﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;


//小红点只有叶子才会有消息

public sealed class SysMsgMgr : Singleton<SysMsgMgr>
{
    private SysMsgMgr() { Init(); }

    //标准UI树形结构
    private Dictionary<ESysRedType, TreeStruct<SysMsgNode>> mDicMsg = new Dictionary<ESysRedType, TreeStruct<SysMsgNode>>();

    //优化搜索的结构,快速找到每一个节点进行操作
    private Dictionary<ESysRedType, TreeStruct<SysMsgNode>> mDicMsgTemp = new Dictionary<ESysRedType, TreeStruct<SysMsgNode>>();


    private List<SysMsgReciever> mListReceivers = new List<SysMsgReciever>();

    private bool mbInited = false;

    private void Init()
    {
        if (mbInited)
            return;

        InitTree(ESysRedType.None, ESysRedType.BagLv1);
        InitTree(ESysRedType.BagLv1, ESysRedType.BagForgeLv2);
        InitTree(ESysRedType.BagLv1, ESysRedType.BagStarLv2);
        InitTree(ESysRedType.BagStarLv2, ESysRedType.BagStarLv3);
        InitTree(ESysRedType.BagForgeLv2, ESysRedType.BagForgeLv3);

        mbInited = true;
    }

    public void Notify(ESysRedType type, SysMsg sm)
    {
        TreeStruct<SysMsgNode> root = null;
        if (mDicMsg.ContainsKey(type))
        {
            root = mDicMsg[type];
            OperationTreeChild(root, sm, true);
        }

        for (int i = 0; i < mListReceivers.Count; i++)
        {
            mListReceivers[i].Notify(sm.mType, true);
        }
        root = null;
    }

    public bool HasNew(ESysRedType type, string guid)
    {
        var node = mDicMsgTemp[type];

        bool result = false;
        if (node.IsChildrenNull())      //是否叶子节点
        {
            if (string.IsNullOrEmpty(guid))
                result = node.Value.MsgCount() > 0;
            else
                result = node.Value.HasMsg(guid);
        }
        else
        {
            List<TreeStruct<SysMsgNode>> list = new List<TreeStruct<SysMsgNode>>();
            int index = 0;
            list.AddRange(node.Children);

            while (list.Count > 0)
            {
                var treeNode = list[index];
                list.RemoveAt(index);
                index = 0;

                if (treeNode.IsChildrenNull())
                {
                    if (string.IsNullOrEmpty(guid))
                        result = treeNode.Value.MsgCount() > 0;
                    else
                        result = node.Value.HasMsg(guid);
                    break;
                }
                else
                {
                    list.AddRange(treeNode.Children);
                }
            }
        }

        return result;
    }

    public bool RemoveMsg(ESysRedType type, string guid = null, bool isNotify = true)
    {
        //guid = null 决定整体删除
        var node = mDicMsgTemp[type];

        bool result = false;
        if (node.IsChildrenNull())      //是否叶子节点
        {
            result = node.Value.MsgCount() == 0;
        }
        else
        {
            List<TreeStruct<SysMsgNode>> list = new List<TreeStruct<SysMsgNode>>();
            int index = 0;
            
            if (string.IsNullOrEmpty(guid))
                list.Add(node);
            else
                list.AddRange(node.Children);

            while (list.Count > 0)
            {
                var treeNode = list[index];
                list.RemoveAt(index);
                index = 0;

                if (string.IsNullOrEmpty(guid))
                {
                    treeNode.Value.RemoveAllMsg();
                    result = true;
                }
                else if (treeNode.IsChildrenNull())
                {
                    result = treeNode.Value.HasMsg(guid);
                    treeNode.Value.RemoveMsg(guid);
                    break;
                }

                list.AddRange(treeNode.Children);
            }
        }

        if (result && isNotify)
        {
            SysMsgReciever sr = null;
            for (int i = 0; i < mListReceivers.Count; i++)
            {
                sr = mListReceivers[i];
                if (string.IsNullOrEmpty(guid))             //通知全部子节点的红点不显示,
                {
                    for (int z = 0; z < sr.ListType.Count; z++)
                    {
                        if (IsParent(type, sr.ListType[z]))
                        {
                            sr.Notify(false);
                            break;
                        }
                        else if (sr.ListType[z] == node.Parent.Value.mType)
                        {
                            sr.Refresh(sr.ListType[z]);
                            break;
                        }
                    }
                }
                else
                    sr.Notify(type, false);
            }
        }
        return result;
    }

    public void AddReciever(SysMsgReciever rec)
    {
        if (!mListReceivers.Contains(rec))
            mListReceivers.Add(rec);
    }

    public void RemoveReceiver(SysMsgReciever rec)
    {
        if (mListReceivers.Contains(rec))
            mListReceivers.Remove(rec);
    }

    public void OperationTreeChild(TreeStruct<SysMsgNode> tree, SysMsg msg, bool add)
    {
        if (tree.Value.mType == msg.mType)
        {
            tree.Value.AddSysMsg(msg);
        }
        else
        {
            if (tree.Children == null)
            {
                PLDebug.LogError("未找到节点: " + msg.mType);
                return;
            }

            TreeStruct<SysMsgNode> node = null;
            List<TreeStruct<SysMsgNode>> list = new List<TreeStruct<SysMsgNode>>();
            list.AddRange(tree.Children);

            int index = 0;
            while (list.Count > 0)
            {
                node = list[index];
                list.RemoveAt(index);
                index = 0;

                //PLDebug.Log("遍历节点:" + node.Value.mType);
                if (node.Value.mType == msg.mType)
                {
                    if (add)
                        node.Value.AddSysMsg(msg);
                    else
                        node.Value.RemoveMsg(msg);
                    break;
                }
                else
                {
                    list.AddRange(node.Children);
                }
            }
        }
    }


    public bool IsParent(ESysRedType parent, ESysRedType child)
    {
        var tree = mDicMsgTemp[child];

        TreeStruct<SysMsgNode> p = null;
        p = tree.Parent;
        bool result = false;

        if (tree.Value.mType == parent)
        {
            result = true;
        }
        else
        {
            while (p != null)
            {
                if (p.Value.mType == parent)
                {
                    result = true;
                    break;
                }

                p = p.Parent;
            }
        }

        return result;
    }

    private void InitTree(ESysRedType parent, ESysRedType child)
    {
        TreeStruct<SysMsgNode> node = null;

        if (parent == ESysRedType.None)
        {
            node = new TreeStruct<SysMsgNode>();
            node.Value = new SysMsgNode();
            node.Value.mType = child;

            mDicMsg.Add(child, node);
            mDicMsgTemp.Add(child, node);
        }
        else
        {
            if (mDicMsgTemp.ContainsKey(parent))
            {
                node = mDicMsgTemp[parent];
                TreeStruct<SysMsgNode> n = new TreeStruct<SysMsgNode>();
                n.Value = new SysMsgNode();
                n.Value.mType = child;
                node.AddChild(n);
                mDicMsgTemp.Add(child, n);
            }
            else
            {
                PLDebug.LogError("不包含:" + parent);
            }


        }
    }



}

public enum ESysRedType     //每一个系统的标记,Lv越高代表层级越深(因为编辑器所以不要中间插入)
{
    None = 1,
    BagLv1 = 2,
    BagForgeLv2 = 3,
    BagForgeLv3 = 4,
    BagStarLv2 = 5,
    BagStarLv3 = 6,
}

public class SysMsgNode         //界面上UI小红点的树形结构
{
    public ESysRedType mType = ESysRedType.None;
    private List<SysMsg> mMsgList;


    public int MsgCount()
    {
        if (mMsgList == null || mMsgList.Count == 0)
            return 0;

        return mMsgList.Count;
    }

    public void AddSysMsg(SysMsg msg)
    {
        if (mMsgList == null)
            mMsgList = new List<SysMsg>();

        mMsgList.Add(msg);
    }

    public bool HasMsg(SysMsg msg)
    {
        return HasMsg(msg.guid);
    }

    public bool HasMsg(string guid)
    {
        if (mMsgList == null)
            return false;

        for (int i = 0; i < mMsgList.Count; i++)
        {
            if (mMsgList[i].guid == guid)
            {
                return true;
            }
        }
        return false;
    }

    public void RemoveMsg(SysMsg msg)
    {
        RemoveMsg(msg.guid);
    }

    public void RemoveMsg(string guid)
    {
        if (mMsgList == null)
            return;

        for (int i = 0; i < mMsgList.Count; i++)
        {
            if (mMsgList[i].guid == guid)
            {
                mMsgList.RemoveAt(i);
                break;
            }
        }
    }

    public void RemoveAllMsg()
    {
        if (mMsgList == null)
            return;
        mMsgList.Clear();
    }
}

public class SysMsg         //系统信息
{
    public ESysRedType mType = ESysRedType.None;
    public string guid = string.Empty;
}

